﻿$(function () {
    /**
     * 表格模板：${}$ 括号内定义动态形参的名字，通过render方法进行渲染
     * 例如：${colname}$ 可通过render(template,{colname:value})将模板中的动态值替换成需要的value
     * Selector:需要在使用模版时实现：将数据对象属性名转换成动态形参名，tips:部署时实现提供转换后的对象或实现转换的方法
     */
    var TblTmp = {
        innerHtmlStart: '<table class="table table-striped table-bordered table-hover table-condensed">',
        innerHtmlEnd:'</table>',
        headTemplate: '<thead>' +
        '<tr>' +    
        '<th style="display:none;">${idCap}$</th>'+    
        '<th class="col-xs-8" style="text-align:center;">${nameCap}$</th>' +
        '<th class="col-xs-2">${colcap1}$</th>' +
        '</tr>' +
        '</thead>',
        contTemplate: '<tr><td class="row-data" style="display:none;">${id}$</td>'+
        '<td style="text-align:center;" class="row-data" > ${name}$</td>' +
        '<td class="row-opt"><div class="dropdown"><button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">操作<span class="caret"></span></button>' +
        '<ul class="dropdown-menu"><li><a class="item del" data-opt="del">删除</a></li><li><a class="item ins" data-opt="ins">插入</a></li></ul></div></td></tr>',
        footTemplate: '<tfoot>' +
        //'<tr>' +
        //'<th colspan="3"><ul class="pager" style="margin:0">'+
        //'<li class="pg"><a id ="pre" class="btn btn-default">&laquo;</a></li>' +
        //'<li class="pg next"><a id ="next">&raquo;</a></li>' +
        //'</ul></th>' +
        //'</tr>' +
        '<tr>' +
        '<th colspan="3"><div class="pull-right" class="btn-group"><div class="btn btn-default" style="display:none;" id="btnEdit">编辑</div><div class="btn btn-default" id="btnCancel">撤销</div><div class="btn btn-default" id="btnSave">保存</div></div></th>' +
        '</tr>' +
        '</tfoot>',
        Selector: { captainSelector: {}, rowSelector: {}},
        render: function (template, args) {
            args = args || {};
            if (!template instanceof String) { alert("模板渲染错误：模板类型错误<not string>！"); return; }
            for (var p in args) {
                if (typeof args[p] == "function") { continue; }
                template = template.replace("${" + p + "}$", args[p]);
            }
            //将剩余的未匹配到的动态参数设为空字符串。<.*?>非贪婪匹配； /.../g g表示每个匹配项都替换
            return template.replace(/\$\{.*?\}\$/g,""); 
        }
    };
    TblTmp.fillTemplate = function (selectorID, data) {
        var colCaps = TblTmp.Selector.captainSelector[selectorID] || {},
            rowSelectorFunc = TblTmp.Selector.rowSelector[selectorID] || function (obj) { return {} };
        var html = TblTmp.innerHtmlStart +
            TblTmp.render(TblTmp.headTemplate, colCaps) +
            "<tbody>";
        if (data instanceof Array && data.length > 0) {
            data.forEach(function (rowObj, i) {
                html += TblTmp.render(TblTmp.contTemplate, rowSelectorFunc(rowObj));
            });
        } else {
            html += TblTmp.render(TblTmp.contTemplate, { });
        }
        html = html + "</tbody>" + TblTmp.footTemplate;
        //html += "</tbody>";
        return html;
    };

    var rowSelector = {
        dpt: { nameCap: "部门" },
        position: { nameCap: "职位" }
    };

    TblTmp.Selector.captainSelector = {
        dpt: { nameCap: "部门" },
        position: { nameCap: "职位" }
    };
    TblTmp.Selector.rowSelector = {
        dpt: function (rowObj) {
            return { name: rowObj.dpt_name, id: rowObj.id };
        },
        position: function (rowObj) { return { name: rowObj.position, id: rowObj.id }; }
    };
    
    /**
     * 按钮点击相应事件
     * 实现功能：撤销 保存
     * @param e event对象
     */
    function btnClick(e) {
        var id = $(e.target).attr("id");
        switch (id) {
            case "btnEdit":
                //var innerHtml = $(e.data + " tbody").html();
                //if (innerHtml == "") {
                //    $(e.data + " tbody").html(innerHtml + TblTmp.render(TblTmp.contTemplate, {}));
                //}

                break;
            case "btnCancel":
                postQryReq(e.data);
                break;
            case "btnSave":
                postSaveReq(e.data);
                break;
        }
    };

    /**
     * table td双击相应事件，实现表格内容的修改
     * 表格编辑完成后post数据到后台
     * @param e
     */
    function cellEdit(e) {
        var cell = $(e.target);
        // 0.清除点击事件  
        cell.parents("tbody").off("dblclick", 'td.row-data', cellEdit);
        // 1.取出cell的原始内容并暂存
        var cellVal = cell.text();
        // 2.清空cell
        cell.html("");
        // 3.建立一个文本输入框,并将暂存的cell原值写入文本框
        var input = $('<input>');
        input.attr('value', cellVal);
        // 4.绑定文本框的失去焦点事件和键盘输入事件：完成编辑时恢复table元素事件绑定
        input.bind("blur", function (event) {
            var inputnode = $(this);            
            var inputtext = inputnode.val();
            var tdNode = inputnode.parent();
            tdNode.html(inputtext);
            cell.parents("tbody").on("dblclick", 'td.row-data', e.data, cellEdit);
        });
        input.keyup(function (event) {
            var myEvent = event || window.event;
            var kcode = myEvent.keyCode;
            // 输入回车时，完成编辑
            if (kcode == 13) {
                var inputnode = $(this);
                var inputtext = inputnode.val();
                var tdNode = inputnode.parent();
                tdNode.html(inputtext);
                cell.parents("tbody").on("dblclick", 'td.row-data', e.data, cellEdit);
            }
        }); 
        //5，将文本框加入到cell中  
        cell.append(input);
        //6. 设置input为当前焦点
        var t = input.val();
        input.val("").focus().val(t);
    };

    /**
     * 表格单条记录操作：新增、删除
     * @param e
     */
    function rowOpts(e) {
        var id = $(e.target).attr("data-opt");
        switch (id) {
            case "del":
                /**
                 * 方案
                 * 1. post后台删除当前记录
                 * 2. ajax操作成功后:
                 * 2.1 删除前台对应tr
                 * 2.2 检查tbody中是否还有tr,如果没有则添加1条空tr
                 */
                var tbody = $(e.target).parents("tbody");
                $(e.target).parents("tr").attr("style", "display:none");
                if (tbody.children('tr[style!="display:none"]').length == 0) {
                    tbody.append(GetEmptyTr(e.data));
                }
                break;
            case "ins":
                /**
                 * 方案
                 * 1. 在当前tr后append一条emptyTr
                 */
                $(e.target).parents("tr").after(GetEmptyTr(e.data));
                break;
        }
    };

    /**
     * 生成table，并给table个元素绑定事件
     * @param tabID
     * @param rows
     */
    function BuildTable(tabID, rows) {
        var tbl_cont = $('div' + tabID);
        // 根据数据生成table
        tbl_cont.html(TblTmp.fillTemplate(tabID.replace('#', ''), rows));

        // 清空绑定的click事件，以防止tab切换时绑定了多次click响应造成的
        // 1次click触发多次click事件
        tbl_cont.find("tfoot").off('click', 'div.btn', btnClick);
        // 给table控制栏添加事件响应
        tbl_cont.find("tfoot").on('click', 'div.btn', tabID, btnClick);

        // cell编辑事件
        tbl_cont.find("tbody").off('dblclick', 'td.row-data', cellEdit);
        tbl_cont.find("tbody").on('dblclick', 'td.row-data', tabID, cellEdit);

        // tr操作事件
        tbl_cont.find("tbody").off('click', 'td.row-opt a.item', rowOpts);
        tbl_cont.find("tbody").on('click', 'td.row-opt a.item', tabID, rowOpts);
    };

    /**
     * 传入激活的tab li->a->href，刷新tab内容
     * @param tabID li->a->href
     */
    function postQryReq(tabID) {
        var data = {
            _csrf: $("meta[name=x-csrf-token]").attr("content"),
            queryID: tabID
        };
        $.post("/querydb", data, function (data, status) {
            if (status == "success") {
                data = JSON.parse(data);
                if (data.code == 200) { BuildTable(tabID, data.data); }
                else {
                    showModal("系统错误", "错误号:" + data.data.code + "\r\n错误信息:" + data.data.errmsg);
                    //alert("系统错误:r\n错误号:" + data.data.code + "\r\n错误信息:" + data.data.errmsg);
                }
            }
        });        
    };

    /**
     * 创建一条空tr并返回
     * @param tabID
     */
    function GetEmptyTr(tabID) {
        var emptyTr = $(TblTmp.render(TblTmp.contTemplate, null));
        /**
         * 不需要重新添加事件，之前的事件绑定都是针对tbody的,selecter用来筛选触发的元素
        // cell编辑事件
        emptyTr.off('dblclick', 'td.row-data', cellEdit);
        emptyTr.on('dblclick', 'td.row-data', tabID, cellEdit);

        // tr操作事件
        emptyTr.off('click', 'td.row-opt a.item', rowOpts);
        emptyTr.on('click', 'td.row-opt a.item', tabID, rowOpts);
        */
        return emptyTr;
    }

    /**
     * 提交数据变更，并刷新表格内容
     * @param tabID
     */
    function postSaveReq(tabID) {
        // 获取数据体
        var rows = $('div' + tabID + ' tbody tr[style!="display:none"]'),
            delRows = $('div' + tabID + ' tbody tr[style="display:none"]'),
            dt = [],
            deltbl = [],
            data;
        rows.each(function (i,row) {
            var dRow = [];
            $(row).find("td.row-data").each(function (j, col) {
                dRow.push($.trim($(col).text()));
            });
            dt.push(dRow);
        });
        delRows.each(function (i, row) {
            var one = [];
            $(row).find("td.row-data").each(function (j, col) {
                one.push($.trim($(col).text()));
            });
            deltbl.push(one);
        });
        data = {
            _csrf: $("meta[name=x-csrf-token]").attr("content"),
            tabID: tabID,
            dataTable: JSON.stringify(dt),
            toDel: JSON.stringify(deltbl)
        };
        // 发送请求
        $.post("/admin/sys-set-upd", data, function (data) {
                data = JSON.parse(data);
                if (data.code == 200) {
                    BuildTable(tabID, data.data);
                    showModal("<strong>保存成功</strong>");
                    //alert("保存成功");
                } else if (data.code == 902) {
                    showModal("系统错误", "<strong>保存成功,但返回结果出错!</strong>\r\n错误号:" + data.data.code + "\r\n错误信息:" + data.data.errmsg);
                    //alert("系统错误:\r\n保存成功,但返回结果出错!\r\n错误号:" + data.data.code + "\r\n错误信息:" +data.data.errmsg);
                } else {
                    showModal("系统错误", "<strong>保存失败！</strong>\r\n错误号:" + data.data.code + "\r\n错误信息:" + data.data.errmsg);
                    //alert("系统错误:\r\n保存失败！\r\n错误号:" + data.data.code + "\r\n错误信息:" +data.data.errmsg);
                }
        }).error(function (jxr, status, msg) {
            showModal("系统错误", "保存失败!\r\n错误信息:<" + jxr.status + ">" + msg);
            //alert("保存失败!\r\n错误信息:<" + jxr.status + ">" + msg);
        });
    };

    $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
        // 获取已激活的标签页
        var activeTab = $(e.target).attr("href");
        // 检查table记录，如果0记录则从后台取记录
        var innerHtml = $(activeTab + " tbody").html()||"";
        if (innerHtml == "") { postQryReq(activeTab); } 
    });

    // 页面load完毕执行数据初始化
    postQryReq($('ul.nav.nav-tabs li.active a').attr("href"));
});